package consul

import (
	"fmt"
	"time"

	"gitee.com/zawei/yggdrasil/pkg/config/encoder"
	"gitee.com/zawei/yggdrasil/pkg/config/source"
	"github.com/hashicorp/consul/api"
)

// Currently a single consul reader
type consul struct {
	addr        string
	prefix      string
	stripPrefix string
	encoder     encoder.Encoder
	client      *api.Client
}

func (c *consul) Read() (*source.ChangeSet, error) {
	kv, _, err := c.client.KV().List(c.prefix, nil)
	if err != nil {
		return nil, err
	}

	if kv == nil || len(kv) == 0 {
		return nil, fmt.Errorf("source not found: %s", c.prefix)
	}

	data, err := makeMap(c.encoder, kv, c.stripPrefix)
	if err != nil {
		return nil, fmt.Errorf("error reading data: %v", err)
	}

	b, err := c.encoder.Encode(data)
	if err != nil {
		return nil, fmt.Errorf("error reading source: %v", err)
	}

	cs := &source.ChangeSet{
		Priority:  source.PriorityRemote,
		Timestamp: time.Now(),
		Format:    c.encoder.String(),
		Source:    c.String(),
		Data:      b,
	}
	cs.Checksum = cs.Sum()

	return cs, nil
}

func (c *consul) String() string {
	return "consul"
}

func (c *consul) Watch() (source.Watcher, error) {
	w, err := newWatcher(c.prefix, c.addr, c.String(), c.stripPrefix, c.encoder)
	if err != nil {
		return nil, err
	}
	return w, nil
}
